package com.bitnpulse.dev2.jjh.engstudybook_free.common;

import java.security.MessageDigest;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * Usage:
 * <pre>
 * String crypto = SimpleCrypto.encrypt(masterpassword, cleartext)
 * ...
 * String cleartext = SimpleCrypto.decrypt(masterpassword, crypto)
 * </pre>
 * 
 * @author ferenc.hechler
 */
public class SimpleCrypto
{
	
	public static final String SEED = "JJS_!@#$";
	
	public static String encrypt(String seed, String cleartext) throws Exception
	{
		byte[] rawKey = getRawKey(seed.getBytes());
		byte[] result = encrypt(rawKey, cleartext.getBytes());
		return toHex(result);
	}
	
	public static String decrypt(String seed, String encrypted) throws Exception
	{
		
//		byte[] rawKeyxxx = (seed.getBytes("UTF-8"));
//		
//		byte[] aa = new byte[8];
//		
//		aa[0] = 74;
//		aa[1] = 74;
//		aa[2] = 83;
//		aa[3] = 95;
//		aa[4] = 33;
//		aa[5] = 64;
//		aa[6] = 35;
//		aa[7] = 36;
//		
//		
//		
//
////		byte[] rawKey = getCompatibleRawKey(seed.getBytes("UTF-8"));
//		
//		byte[] rawKey = getRawKey(aa);
		
		
		byte[] bb = new byte[16];
		
		bb[0] = -6;
		bb[1] = -20;
		bb[2] = -23;
		bb[3] = 108;
		bb[4] = 118;
		bb[5] = 65;
		bb[6] = -119;
		bb[7] = -5;
		bb[8] = 24;
		bb[9] = -15;
		bb[10] = -54;
		bb[11] = 42;
		bb[12] = 81;
		bb[13] = 88;
		bb[14] = 7;
		bb[15] = -7;
		
		
		byte[] enc = toByte(encrypted);
		byte[] result = decrypt(bb, enc);
		
//		for (int i = 0; i < result.length; i++) {
//			System.out.println("JJJ" + i + " ::" + result[i]);
//		}
		
		
		return new String(result);
	}

	
	private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception
	{
	    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
		Cipher cipher = Cipher.getInstance("AES");
	    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
	    byte[] encrypted = cipher.doFinal(clear);
		return encrypted;
	}

	private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception
	{
	    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
		Cipher cipher = Cipher.getInstance("AES");
	    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
	    byte[] decrypted = cipher.doFinal(encrypted);
		return decrypted;
	}

	public static String toHex(String txt)
	{
		return toHex(txt.getBytes());
	}
	
	public static String fromHex(String hex)
	{
		return new String(toByte(hex));
	}
	
	public static byte[] toByte(String hexString)
	{
		int len = hexString.length()/2;
		byte[] result = new byte[len];
		for (int i = 0; i < len; i++)
			result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
		return result;
	}
	
//	private static byte[] getCompatibleRawKey(byte[] seed) throws Exception {
//	    KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
//	    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
//	    sr.setSeed(seed); 
//	    kgen.init(128, sr); // 192 and 256 bits may not be available 
//	    SecretKey skey = kgen.generateKey(); 
//	    byte[] raw = skey.getEncoded(); 
//	    return raw; 
//	}

//	private static byte[] getRawKey(byte[] seed) throws Exception { 
//	    MessageDigest md = MessageDigest.getInstance("MD5"); 
//	    byte[] md5Bytes = md.digest(seed); // 128 Bit = 16 byte SecretKey 
//	    SecretKeySpec skey = new SecretKeySpec(md5Bytes, "AES"); 
//	    byte[] raw = skey.getEncoded(); 
//	    return raw; 
//	}
	
	private static byte[] getRawKey(byte[] seed) throws Exception
	{
		KeyGenerator kgen = KeyGenerator.getInstance("AES");
		SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
		sr.setSeed(seed);
	    kgen.init(128, sr); // 192 and 256 bits may not be available
	    SecretKey skey = kgen.generateKey();
	    byte[] raw = skey.getEncoded();
	    return raw;
	}
	
	public static String toHex(byte[] buf)
	{
		if (buf == null)
			return "";
		StringBuffer result = new StringBuffer(2*buf.length);
		for (int i = 0; i < buf.length; i++) {
			appendHex(result, buf[i]);
		}
		return result.toString();
	}
	
	private final static String HEX = "0123456789ABCDEF";
	private static void appendHex(StringBuffer sb, byte b)
	{
		sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
	}
	
}

// see http://www.androidsnippets.com/encryptdecrypt-strings